# ifndef __ParseHelpers_H_
# define __ParseHelpers_H_

bool IsBinary (const char * _pBegin, const char * _pEnd);


	//
	// Helpers for text parsers.
	//

// Find substing, ignore case. Return NULL if not found.
char * FindIStr (const char * _str, const char * _strSub);
// Return true for data in Unicode.
bool CheckAnsiFile (const char * _pData, size_t _cFileSize, bool _bSilent);
// Check string for prexix mathing. Case-insensitive.
bool __fastcall HasPrefix (const char * _p, const char * _pEnd, const char * _pPrefix, size_t _cPrefixLen);
// Search for next line start. On fail, _pEnd is returned.
const char * __fastcall FindNextLine (const char * _pBegin, const char * _pEnd);
// Return length of segment up to last CR, TAB, SPACE etc symbols.
size_t GetLineLen (const char * _pBegin, const char * _pNextLine);
// Find first non-space character.
void OmitSpaces (const char ** _pp, const char * _pEnd);
// Find first space cahracter.
void OmitNonSpaces (const char ** _pp, const char * _pEnd);
// Remove leading and tailing spaces.
void StripSpaces (char * _str);

	//
	// Parse unsigned decimal number.
	//
bool ParseDecU (const char    * _pValue, const char    * _pEnd, const char    ** _ppEnd, unsigned long & _ulRet);
bool ParseDecU (const wchar_t * _pValue, const wchar_t * _pEnd, const wchar_t ** _ppEnd, unsigned long & _ulRet);

inline
unsigned long ParseDecU (const char * _pValue, const char * _pEnd) {
	const char * p;
	unsigned long ulRet;
	ParseDecU (_pValue, _pEnd, & p, ulRet);
	return ulRet;
}

inline
unsigned long ParseDecU (const string_t & _strValue) {
	return ParseDecU (_strValue.c_str (), _strValue.c_str () + _strValue.size ());
}

	//
	// Parse hexadecimal number.
	//
bool ParseHex (const char * _pValue, const char * _pEnd, const char ** _ppEnd, unsigned long & _ulRet);

inline
unsigned long ParseHex (const char * _pValue, const char * _pEnd) {
	const char * p;
	unsigned long ulRet;
	ParseHex (_pValue, _pEnd, & p, ulRet);
	return ulRet;
}

inline
unsigned long ParseHex (const string_t & _strValue) {
	return ParseHex (_strValue.c_str (), _strValue.c_str () + _strValue.size ());
}

	//
	// Parse fixed-point real number.
	//
bool ParseReal (const char * _pValue, const char * _pEnd, const char ** _ppEnd, float & _fRet);
bool ParseReal (const char * _pValue, const char * _pEnd, const char ** _ppEnd, double & _fRet);
bool ParseReal (const wchar_t * _pValue, const wchar_t * _pEnd, const wchar_t ** _ppEnd, float & _fRet);

inline
float ParseReal (const char * _pValue, const char * _pEnd) {
	const char * p;
	float fRet;
	ParseReal (_pValue, _pEnd, & p, fRet);
	return fRet;
}

inline
float ParseReal (const string_t & _strValue) {
	return ParseReal (_strValue.c_str (), _strValue.c_str () + _strValue.size ());
}

inline
float ParseReal (const wchar_t * _pValue, const wchar_t * _pEnd) {
	const wchar_t * p;
	float fRet;
	return ParseReal (_pValue, _pEnd, & p, fRet) ? fRet : 0;
}


	//
	//
	//
bool ParseArc (const char * _pValue, const char * _pEnd, const char ** _ppEnd, float & _fRet, bool _bRequireDegSign = true);

inline
float ParseArc (const char * _pValue, const char * _pEnd) {
	const char * p;
	float fRet;
	ParseArc (_pValue, _pEnd, & p, fRet);
	return fRet;
}

inline
float ParseArc (const string_t & _strValue) {
	return ParseArc (_strValue.c_str (), _strValue.c_str () + _strValue.size ());
}



	//
	// Helpers for binary parsers.
	//

// Convert big-endian DWORD to low-endian one.
inline
DWORD Big2LowEndian (DWORD _dw) {
	const BYTE * const ba = reinterpret_cast<BYTE *> (& _dw);
	return (ba [0] << 24) + (ba [1] << 16) + (ba [2] << 8) + ba [3];
}

inline
size_t Align4 (size_t _c) {
	if (_c & 0x3)
		_c += 4 - (_c & 0x3);
	assert (_c % 4 == 0);
	return _c;
}

inline
size_t Align2 (size_t _c) {
	if (_c & 0x1)
		++ _c;
	assert (_c % 2 == 0);
	return _c;
}

# endif // __ParseHelpers_H_